package org.zjvis.datascience.web.controller;

import cn.weiguangfu.swagger2.plus.annotation.ApiGroup;
import cn.weiguangfu.swagger2.plus.annotation.ApiPlus;
import cn.weiguangfu.swagger2.plus.enums.ApiExecutionEnum;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.io.InputStream;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.zjvis.datascience.common.annotation.ProjectRoleAuth;
import org.zjvis.datascience.common.constant.Constant;
import org.zjvis.datascience.common.enums.ProjectRoleAuthEnum;
import org.zjvis.datascience.common.exception.BaseErrorCode;
import org.zjvis.datascience.common.exception.DataScienceException;
import org.zjvis.datascience.common.model.ApiResult;
import org.zjvis.datascience.common.model.ApiResultCode;
import org.zjvis.datascience.common.util.FileUtil;
import org.zjvis.datascience.common.vo.PipelineSnapshotQueryVO;
import org.zjvis.datascience.common.vo.PipelineSnapshotVO;
import org.zjvis.datascience.service.PipelineSnapshotService;

/**
 * @description pipeline快照接口 Controller
 * @date 2021-09-07
 */
@ApiPlus(value = true)
@RequestMapping("pipeline/")
@RestController
@Api(tags = "pipeline snapshot", description = "pipeline快照接口")
public class PipelineSnapshotController {

    private final static Logger logger = LoggerFactory.getLogger(PipelineSnapshotController.class);

    @Autowired
    PipelineSnapshotService pipelineSnapshotService;

//    @ApiGroup(groups = PipelineSnapshotVO.Save.class, requestExecution = ApiExecutionEnum.INCLUDE)
//    @PostMapping(value = "snapshot/saveSnapshot")
//    @ApiOperation(value = "保存快照", notes = "保存pipeline快照")
//    public ApiResult<Boolean> saveSnapshot(@ProjectRoleAuth(role = ProjectRoleAuthEnum.DEVELOPER)
//    @Validated(PipelineSnapshotVO.Save.class) @RequestBody PipelineSnapshotVO vo) throws Exception {
//        Boolean res = pipelineSnapshotService.saveSnapshot(vo);
//        return ApiResult.valueOf(res);
//    }

    @ApiGroup(groups = PipelineSnapshotVO.Check.class, requestExecution = ApiExecutionEnum.INCLUDE)
    @PostMapping(value = "snapshot/checkSnapshotThreshold")
    @ApiOperation(value = "检查快照容量阈值", notes = "检查快照容量是否已满")
    public ApiResult<Boolean> checkSnapshotThreshold(
        @ProjectRoleAuth(role = ProjectRoleAuthEnum.DEVELOPER)
        @Validated(PipelineSnapshotVO.Check.class) @RequestBody PipelineSnapshotVO vo) {
        JSONObject res = pipelineSnapshotService.checkSnapshotThreshold(vo.getPipelineId());
        return ApiResult
            .valueOf(ApiResultCode.SUCCESS, res.getBoolean("useful"), res.getString("tips"));
    }

    @ApiGroup(groups = PipelineSnapshotVO.Delete.class, requestExecution = ApiExecutionEnum.INCLUDE)
    @PostMapping(value = "snapshot/deleteSnapshot")
    @ApiOperation(value = "删除快照", notes = "删除pipeline快照")
    public ApiResult<Boolean> deleteSnapshot(@ProjectRoleAuth(role = ProjectRoleAuthEnum.DEVELOPER)
    @Validated(PipelineSnapshotVO.Delete.class) @RequestBody PipelineSnapshotVO vo)
        throws Exception {
        Boolean res = pipelineSnapshotService.deleteSnapshot(vo);
        return ApiResult.valueOf(res);
    }

    @ApiGroup(groups = PipelineSnapshotVO.Recover.class, requestExecution = ApiExecutionEnum.INCLUDE)
    @PostMapping(value = "snapshot/recoverSnapshot")
    @ApiOperation(value = "恢复快照", notes = "恢复pipeline快照")
    public ApiResult<Boolean> recoverSnapshot(@ProjectRoleAuth(role = ProjectRoleAuthEnum.DEVELOPER)
    @Validated(PipelineSnapshotVO.Recover.class) @RequestBody PipelineSnapshotVO vo) {
        Boolean res = pipelineSnapshotService.recoverSnapshot(vo);
        return ApiResult.valueOf(res);
    }

    @ApiGroup(groups = PipelineSnapshotVO.Query.class, requestExecution = ApiExecutionEnum.INCLUDE)
    @PostMapping(value = "snapshot/querySnapshot")
    @ApiOperation(value = "获取快照", notes = "获取快照")
    public ApiResult<List<PipelineSnapshotQueryVO>> querySnapshot(
        @ProjectRoleAuth(role = ProjectRoleAuthEnum.DEVELOPER)
        @Validated(PipelineSnapshotVO.Query.class) @RequestBody PipelineSnapshotVO vo) {
        return ApiResult.valueOf(pipelineSnapshotService.queryByPipeline(vo.getPipelineId()));
    }


    @PostMapping(value = "snapshot/saveSnapshot")
    @ApiOperation(value = "保存快照", notes = "保存pipeline快照")
    public ApiResult<Boolean> saveSnapshot2(
        @Valid @NotNull @RequestParam("picture") MultipartFile picture,
        @RequestParam(value = "projectId") long projectId,
        @RequestParam(value = "pipelineId") long pipelineId,
        @RequestParam(value = "pipelineSnapshotName") String pipelineSnapshotName)
        throws Exception {
        PipelineSnapshotVO pv = new PipelineSnapshotVO();
        InputStream in = picture.getInputStream();
        if (in.available() == 0) {
            logger.warn("API /pipeline/snapshot/saveSnapshot failed, since {}", "image is empty");
            throw new DataScienceException(BaseErrorCode.PIPELINE_SNAPSHOT_PICTURE_NOT_NULL,
                new RuntimeException());
        }
        if (StringUtils.isBlank(pipelineSnapshotName)) {
            logger.warn("API /pipeline/snapshot/saveSnapshot failed, since {}", "name is empty");
            throw new DataScienceException(BaseErrorCode.PIPELINE_SNAPSHOT_NAME_NOT_NULL,
                new RuntimeException());
        }
        if (projectId < 1) {
            logger.warn("API /pipeline/snapshot/saveSnapshot failed, since {}", "projectId is empty");
            throw new DataScienceException(BaseErrorCode.PIPELINE_SNAPSHOT_PROJECT_INVALID,
                new RuntimeException());
        }
        if (pipelineId < 1) {
            logger.warn("API /pipeline/snapshot/saveSnapshot failed, since {}", "pipelineId is empty");
            throw new DataScienceException(BaseErrorCode.PIPELINE_SNAPSHOT_PIPELINE_INVALID,
                new RuntimeException());
        }
        pv.setPicture(Constant.PIPELINE_SNAPSHOT_PICTURE_PREFIX + FileUtil.inputStream2Base64(in));
        pv.setProjectId(projectId);
        pv.setPipelineId(pipelineId);
        pv.setPipelineSnapshotName(pipelineSnapshotName);
        Boolean res = pipelineSnapshotService.saveSnapshot(pv);
        return ApiResult.valueOf(res);
    }

}
